package be.fedict.eid.diagnostics.system.windows.proxies;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.ptr.IntByReference;

public interface Advapi32 extends com.sun.jna.platform.win32.Advapi32 {

	Advapi32 INSTANCE = (Advapi32) Native.loadLibrary("Advapi32", Advapi32.class);

	public static final int SC_ENUM_PROCESS_INFO = 0x0;

	public static final int SERVICE_INTERACTIVE_PROCESS = 0x00000100;
	public static final int SERVICE_ADAPTER = 0x00000004;
	public static final int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
	public static final int SERVICE_WIN32_SHARE_PROCESS = 0x00000020;
	public static final int SERVICE_KERNEL_DRIVER = 0x00000001;
	public static final int SERVICE_FILE_SYSTEM_DRIVER = 0x00000002;
	public static final int SERVICE_RECOGNIZER_DRIVER = 0x00000008;
	public static final int SERVICE_DRIVER = 0x0000000B;
	public static final int SERVICE_WIN32 = 0x00000030;
	public static final int SERVICE_STATE_ALL = 0x00000003;
	
	public static final String SERVICES_ACTIVE_DATABASE = "ServicesActive";
	
	public static final int GENERIC_READ = 0x80000000;
	
	/**
	 * 
	 */
	public class SERVICE_STATUS_PROCESS extends Structure {
		public int dwServiceType;
		public int dwCurrentState;
		public int dwControlsAccepted;
		public int dwWin32ExitCode;
		public int dwServiceSpecificExitCode;
		public int dwCheckPoint;
		public int dwWaitHint;
		public int dwProcessId;
		public int dwServiceFlags;		
	}
	
	/**
	 * 
	 */
	public class ENUM_SERVICE_STATUS_PROCESS extends Structure {
		
		public ENUM_SERVICE_STATUS_PROCESS() {
		      super();
		}
		
		public ENUM_SERVICE_STATUS_PROCESS(Memory buf) {
		     super(buf);
		}
		
		public String lpServiceName;
		public String lpDisplayName;
		public SERVICE_STATUS_PROCESS ServiceStatusProcess;
	}
	
	/**
	 * 
	 */
	public static class LUID extends Structure {
        public int LowPart; 
        public NativeLong HighPart; 
	}
	
	/**
	 * 
	 */
	public class LUID_AND_ATTRIBUTES extends Structure {
		public LUID Luid;
		public int Attributes;
	}
	
	/** 
	*/
	public class TOKEN_PRIVILEGES extends Structure {
		public DWORD PrivilegeCount;
		public LUID_AND_ATTRIBUTES[] Privileges;

		public TOKEN_PRIVILEGES(final DWORD PrivilegeCount) {
			this.PrivilegeCount = PrivilegeCount;
			Privileges = new LUID_AND_ATTRIBUTES[PrivilegeCount.intValue()];
			allocateMemory();
		}
	}
	
	/**
	 * The LookupPrivilegeValue function retrieves the locally 
	 * unique identifier (LUID) used on a specified system to 
	 * locally represent the specified privilege name.
	 * 
	 * http://msdn.microsoft.com/en-us/library/aa379180(VS.85).aspx
	 */
	boolean LookupPrivilegeValueA(
			String lpSystemName,
			String lpName,
			LUID lpLuid);
	
	/**
	 * The AdjustTokenPrivileges function enables or disables 
	 * privileges in the specified access token. Enabling or 
	 * disabling privileges in an access token requires 
	 * TOKEN_ADJUST_PRIVILEGES access.
	 * 
	 * http://msdn.microsoft.com/en-us/library/aa375202(VS.85).aspx
	 */
	boolean AdjustTokenPrivileges(
			HANDLE TokenHandle,
			boolean DisableAllPrivileges,
			TOKEN_PRIVILEGES NewState,
			int BufferLength,
			TOKEN_PRIVILEGES PreviousState,
			IntByReference ReturnLength);
	
	/**
	 * Establishes a connection to the service control manager 
	 * on the specified computer and opens the specified service 
	 * control manager database.
	 * 
	 * http://msdn.microsoft.com/en-us/library/ms684323(VS.85).aspx
	 */
	HANDLE OpenSCManagerA(
			String lpMachineName,
			String lpDatabaseName,
			int dwDesiredAccess); 
	
	
	/**
	 * Open an existing service
	 * 
	 * http://msdn.microsoft.com/en-us/library/ms684330(VS.85).aspx
	 */
//	HANDLE OpenService(
//			HANDLE hSCManager,
//			String lpServiceName,
//			int dwDesiredAccess);

	/**
	 * 
	 */
	boolean EnumServicesStatusExA(
			HANDLE hSCManager,
			int InfoLevel,
			int dwServiceType,
			int dwServiceState,
			Memory buf,
			int cbBufSize,
			IntByReference pcbBytesNeeded,
			IntByReference lpServicesReturned,
			IntByReference lpResumeHandle,
			String pszGroupName);
	
}
